﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.DB;
using YJKArchUtils.Utils;
using YJKRevitRampModule.Utils;

namespace YJKRevitRampModule.CreateRampByDoor
{
	public class RampPlotter
	{
		public List<CurveInfo> Curves
		{
			get
			{
				return this.m_Curves;
			}
		}

		public List<TextNoteInfo> Texts
		{
			get
			{
				return this.m_Texts;
			}
		}

		public List<FillRegion> FillRegions
		{
			get
			{
				return this.m_FillRegions;
			}
		}

		public void Draw(RampType rampType, Transform transform, double rampLength, double rampHeight, double rampWidth, double rampBottomWidth, double rampVOffset, double rampHOffset, SkidResistanceType rampSkidResistanceType, List<List<EdgeInfo>> doorLoops, List<bool> isGlass, double wallThickness)
		{
			this.m_CurrentTransform = transform;
			double halfWidth = rampWidth / 2.0;
			double halfWallThick = wallThickness / 2.0;
			if (rampType == RampType.RT_Person)
			{
				this.DrawPersonRamp(halfWidth, halfWallThick, rampLength, rampHeight, rampVOffset, rampHOffset, rampSkidResistanceType, wallThickness, doorLoops, isGlass);
			}
			else
			{
				double halfBottomWidth = rampBottomWidth / 2.0;
				this.DrawCarRamp(halfWidth, halfBottomWidth, halfWallThick, rampLength, rampHeight, rampVOffset, rampHOffset, rampSkidResistanceType, wallThickness, doorLoops, isGlass);
			}
			this.m_FillRegions.Sort(new FillRegionZComparer());
		}

		private void DrawPersonRamp(double halfWidth, double halfWallThick, double rampLength, double rampHeight, double rampVOffset, double rampHOffset, SkidResistanceType rampSkidResistanceType, double wallThickness, List<List<EdgeInfo>> doorLoops, List<bool> isGlass)
		{
			XYZ xyz = this.NewPoint(-halfWidth, -rampLength - rampHOffset - halfWallThick, rampVOffset, this.m_CurrentTransform);
			XYZ xyz2 = this.NewPoint(halfWidth, -rampLength - rampHOffset - halfWallThick, rampVOffset, this.m_CurrentTransform);
			XYZ xyz3 = this.NewPoint(-halfWidth, -rampHOffset - halfWallThick, rampVOffset, this.m_CurrentTransform);
			XYZ xyz4 = this.NewPoint(halfWidth, -rampHOffset - halfWallThick, rampVOffset, this.m_CurrentTransform);
			XYZ xyz5 = this.NewPoint(-halfWidth, -rampHOffset - halfWallThick, rampHeight + rampVOffset, this.m_CurrentTransform);
			XYZ xyz6 = this.NewPoint(halfWidth, -rampHOffset - halfWallThick, rampHeight + rampVOffset, this.m_CurrentTransform);
			this.DrawRamp(xyz, xyz2, xyz3, xyz4, xyz5, xyz6, rampSkidResistanceType, this.m_CurrentTransform, PenColor.PC_LightGray);
			this.DrawDoor(doorLoops, isGlass, wallThickness, rampHeight, this.m_CurrentTransform);
			PenColor color = PenColor.PC_Black;
			double sideWidth = 2.0;
			if (Geometry.GreaterThan(rampHOffset, 0.0))
			{
				XYZ xyz7 = (xyz6 - xyz4).Normalize();
				XYZ xyz8 = (xyz2 - xyz).Normalize();
				XYZ xyz9 = xyz7.CrossProduct(xyz8);
				XYZ ptStart = this.NewPoint(-halfWidth, -halfWallThick, rampVOffset, this.m_CurrentTransform);
				XYZ xyz10 = this.NewPoint(halfWidth, -halfWallThick, rampVOffset, this.m_CurrentTransform);
				XYZ xyz11 = this.NewPoint(-halfWidth, -halfWallThick, rampHeight + rampVOffset, this.m_CurrentTransform);
				XYZ xyz12 = this.NewPoint(halfWidth, -halfWallThick, rampHeight + rampVOffset, this.m_CurrentTransform);
				this.DrawPole(ptStart, xyz3, xyz7, sideWidth, color);
				this.DrawPole(xyz10, xyz4, xyz7, sideWidth, color);
				this.DrawPole(xyz11, xyz5, xyz7, sideWidth, color);
				this.DrawPole(xyz12, xyz6, xyz7, sideWidth, color);
				this.DrawPole(ptStart, xyz11, -xyz9, sideWidth, color);
				this.DrawPole(xyz10, xyz12, -xyz9, sideWidth, color);
				this.DrawPole(ptStart, xyz10, xyz7, sideWidth, color);
				this.DrawPole(xyz11, xyz12, xyz7, sideWidth, color);
			}
		}

		private void DrawCarRamp(double halfWidth, double halfBottomWidth, double halfWallThick, double rampLength, double rampHeight, double rampVOffset, double rampHOffset, SkidResistanceType rampSkidResistanceType, double wallThickness, List<List<EdgeInfo>> doorLoops, List<bool> isGlass)
		{
			XYZ xyz = this.NewPoint(-halfBottomWidth, -rampLength - rampHOffset - halfWallThick, rampVOffset, this.m_CurrentTransform);
			XYZ xyz2 = this.NewPoint(halfBottomWidth, -rampLength - rampHOffset - halfWallThick, rampVOffset, this.m_CurrentTransform);
			XYZ xyz3 = this.NewPoint(-halfBottomWidth, -rampHOffset - halfWallThick, rampVOffset, this.m_CurrentTransform);
			XYZ xyz4 = this.NewPoint(halfBottomWidth, -rampHOffset - halfWallThick, rampVOffset, this.m_CurrentTransform);
			XYZ xyz5 = this.NewPoint(-halfWidth, -rampHOffset - halfWallThick, rampHeight + rampVOffset, this.m_CurrentTransform);
			XYZ xyz6 = this.NewPoint(halfWidth, -rampHOffset - halfWallThick, rampHeight + rampVOffset, this.m_CurrentTransform);
			this.DrawRamp(xyz, xyz2, xyz3, xyz4, xyz5, xyz6, rampSkidResistanceType, this.m_CurrentTransform, PenColor.PC_LightGray);
			this.DrawDoor(doorLoops, isGlass, wallThickness, rampHeight, this.m_CurrentTransform);
			PenColor color = PenColor.PC_Black;
			double sideWidth = 2.0;
			if (Geometry.GreaterThan(rampHOffset, 0.0))
			{
				XYZ xyz7 = (xyz6 - xyz4).Normalize();
				XYZ xyz8 = (xyz2 - xyz).Normalize();
				XYZ xyz9 = xyz7.CrossProduct(xyz8);
				XYZ ptStart = this.NewPoint(-halfBottomWidth, -halfWallThick, rampVOffset, this.m_CurrentTransform);
				XYZ xyz10 = this.NewPoint(halfBottomWidth, -halfWallThick, rampVOffset, this.m_CurrentTransform);
				XYZ xyz11 = this.NewPoint(-halfWidth, -halfWallThick, rampHeight + rampVOffset, this.m_CurrentTransform);
				XYZ xyz12 = this.NewPoint(halfWidth, -halfWallThick, rampHeight + rampVOffset, this.m_CurrentTransform);
				this.DrawPole(ptStart, xyz3, xyz7, sideWidth, color);
				this.DrawPole(xyz10, xyz4, xyz7, sideWidth, color);
				this.DrawPole(xyz11, xyz5, xyz7, sideWidth, color);
				this.DrawPole(xyz12, xyz6, xyz7, sideWidth, color);
				this.DrawPole(ptStart, xyz11, -xyz9, sideWidth, color);
				this.DrawPole(xyz10, xyz12, -xyz9, sideWidth, color);
				this.DrawPole(ptStart, xyz10, xyz7, sideWidth, color);
				this.DrawPole(xyz11, xyz12, xyz7, sideWidth, color);
			}
		}

		private void DrawRamp(XYZ ptFrontLeftBottom, XYZ ptFrontRightBottom, XYZ ptBackLeftBottom, XYZ ptBackRightBottom, XYZ ptBackLeftTop, XYZ ptBackRightTop, SkidResistanceType rampSkidResistanceType, Transform transform, PenColor profileColor)
		{
			this.DrawFace(new List<XYZ>
			{
				ptFrontLeftBottom,
				ptBackLeftTop,
				ptBackLeftBottom
			}, profileColor);
			this.DrawFace(new List<XYZ>
			{
				ptFrontRightBottom,
				ptBackRightBottom,
				ptBackRightTop
			}, profileColor);
			this.DrawFace(new List<XYZ>
			{
				ptBackLeftBottom,
				ptBackLeftTop,
				ptBackRightTop,
				ptBackRightBottom
			}, profileColor);
			if (rampSkidResistanceType == SkidResistanceType.SRT_None)
			{
				this.DrawFace(new List<XYZ>
				{
					ptFrontLeftBottom,
					ptFrontRightBottom,
					ptBackRightTop,
					ptBackLeftTop
				}, profileColor);
				return;
			}
			this.DrawSkidResistance(ptFrontLeftBottom, ptFrontRightBottom, ptBackLeftTop, ptBackRightTop, transform, profileColor, rampSkidResistanceType);
		}

		private void DrawSkidResistance(XYZ ptFrontLeftBottom, XYZ ptFrontRightBottom, XYZ ptBackLeftTop, XYZ ptBackRightTop, Transform transform, PenColor profileColor, SkidResistanceType rampSkidResistanceType)
		{
			double length = (ptBackLeftTop - ptFrontLeftBottom).GetLength();
			double num = 60.0;
			double num2 = 15.0;
			int num3 = Common.GetInt(length / num) - 1;
			XYZ xyz = (ptBackLeftTop - ptFrontLeftBottom).Normalize();
			XYZ xyz2 = (ptBackRightTop - ptFrontRightBottom).Normalize();
			double num4 = num;
			PenColor profileColor2 = PenColor.PC_Black;
			if (rampSkidResistanceType == SkidResistanceType.SRT_Concave)
			{
				profileColor2 = PenColor.PC_White;
			}
			XYZ xyz3 = (ptFrontRightBottom - ptFrontLeftBottom).Normalize();
			for (int i = 1; i <= num3; i++)
			{
				List<XYZ> list = new List<XYZ>();
				XYZ item = ptFrontLeftBottom + xyz * (num * (double)i - num2);
				XYZ item2 = ptFrontRightBottom + xyz2 * (num * (double)i - num2);
				XYZ item3 = ptFrontLeftBottom + xyz * (num * (double)i + num2);
				XYZ item4 = ptFrontRightBottom + xyz2 * (num * (double)i + num2);
				list.Add(item);
				list.Add(item2);
				list.Add(item4);
				list.Add(item3);
				this.DrawFace(list, profileColor2);
				XYZ item5 = ptFrontLeftBottom + xyz * (num * (double)(i - 1) + num2);
				XYZ item6 = ptFrontRightBottom + xyz2 * (num * (double)(i - 1) - num2);
				if (i == 1)
				{
					item5 = ptFrontLeftBottom;
					item6 = ptFrontRightBottom;
				}
				List<XYZ> list2 = new List<XYZ>();
				list2.Add(item5);
				list2.Add(item6);
				list2.Add(item2);
				list2.Add(item);
				this.DrawFace(list2, profileColor);
				if (i == num3)
				{
					list2.Clear();
					list2.Add(item3);
					list2.Add(item4);
					list2.Add(ptBackRightTop);
					list2.Add(ptBackLeftTop);
					this.DrawFace(list2, profileColor);
				}
				this.DrawFace(new List<XYZ>
				{
					ptFrontLeftBottom,
					ptFrontLeftBottom + xyz3 * num4,
					ptBackLeftTop + xyz3 * num4,
					ptBackLeftTop
				}, profileColor);
				this.DrawFace(new List<XYZ>
				{
					ptFrontRightBottom - xyz3 * num4,
					ptFrontRightBottom,
					ptBackRightTop,
					ptBackRightTop - xyz3 * num4
				}, profileColor);
			}
		}

		private void DrawDoor(List<List<EdgeInfo>> doorLoops, List<bool> isGlass, double wallThickness, double elevationOffset, Transform transform)
		{
			Transform transform2 = RevitVersionFuncs.CreateTranslation(new XYZ(0.0, wallThickness / 2.0, elevationOffset));
			Transform transform3 = transform.Multiply(transform2);
			int num = 0;
			foreach (List<EdgeInfo> list in doorLoops)
			{
				List<XYZ> list2 = new List<XYZ>();
				int i = 0;
				XYZ xyz = list[i].EndPoint;
				if (!xyz.IsAlmostEqualTo(list[i + 1].StartPoint) && !xyz.IsAlmostEqualTo(list[i + 1].EndPoint))
				{
					xyz = list[i].StartPoint;
				}
				list2.Add(xyz);
				for (i = 1; i < list.Count; i++)
				{
					XYZ xyz2 = list2[list2.Count - 1];
					XYZ xyz3 = list[i].EndPoint;
					if (xyz2.IsAlmostEqualTo(xyz3))
					{
						xyz3 = list[i].StartPoint;
					}
					list2.Add(xyz3);
				}
				List<XYZ> list3 = new List<XYZ>();
				foreach (XYZ xyz4 in list2)
				{
					XYZ xyz5 = new XYZ(Common.FeetToMM(xyz4.X), Common.FeetToMM(xyz4.Y), Common.FeetToMM(xyz4.Z));
					xyz5 = Geometry.TransformPoint(xyz5, transform3);
					list3.Add(xyz5);
				}
				PenColor color = PenColor.PC_Yellow;
				if (isGlass[num])
				{
					color = PenColor.PC_LightBlue;
				}
				FillRegion fillRegion = this.CreateFillRegions(list3, color);
				if (fillRegion.EdgeLoop.Count == 3)
				{
					fillRegion.SetEdgeTransparent(0);
					fillRegion.SetEdgeTransparent(1);
					fillRegion.SetEdgeTransparent(2);
				}
				this.AddFillRegion(fillRegion);
				num++;
			}
		}

		private XYZ TransformPoint(XYZ pt, Transform transform)
		{
			return Geometry.TransformPoint(pt, transform);
		}

		private XYZ NewPoint(double x, double y, double z, Transform transform)
		{
			XYZ pt = new XYZ(x, y, z);
			return this.TransformPoint(pt, transform);
		}

		private void AddFillRegion(FillRegion region)
		{
			if (Geometry.GreaterThan(region.Normal().Z, 0.0))
			{
				return;
			}
			this.m_FillRegions.Add(region);
		}

		private void DrawFace(List<XYZ> loop, PenColor profileColor)
		{
			FillRegion region = this.CreateFillRegions(loop, profileColor);
			this.AddFillRegion(region);
		}

		private void DrawPole(XYZ ptStart, XYZ ptEnd, XYZ vtUp, double sideWidth, PenColor color)
		{
			double num = sideWidth / 2.0;
			XYZ xyz = (ptEnd - ptStart).Normalize().CrossProduct(vtUp);
			XYZ item = ptStart - xyz * num - vtUp * num;
			XYZ item2 = ptStart - xyz * num + vtUp * num;
			XYZ item3 = ptStart + xyz * num - vtUp * num;
			XYZ item4 = ptStart + xyz * num + vtUp * num;
			XYZ item5 = ptEnd - xyz * num - vtUp * num;
			XYZ item6 = ptEnd - xyz * num + vtUp * num;
			XYZ item7 = ptEnd + xyz * num - vtUp * num;
			XYZ item8 = ptEnd + xyz * num + vtUp * num;
			this.DrawFace(new List<XYZ>
			{
				item,
				item3,
				item4,
				item2
			}, color);
			this.DrawFace(new List<XYZ>
			{
				item7,
				item5,
				item6,
				item8
			}, color);
			this.DrawFace(new List<XYZ>
			{
				item2,
				item4,
				item8,
				item6
			}, color);
			this.DrawFace(new List<XYZ>
			{
				item3,
				item,
				item5,
				item7
			}, color);
			this.DrawFace(new List<XYZ>
			{
				item,
				item2,
				item6,
				item5
			}, color);
			this.DrawFace(new List<XYZ>
			{
				item3,
				item7,
				item8,
				item4
			}, color);
		}

		private FillRegion CreateFillRegions(List<XYZ> loop, PenColor color)
		{
			List<EdgeInfo> list = new List<EdgeInfo>();
			for (int i = 0; i < loop.Count; i++)
			{
				XYZ startPoint = loop[i];
				XYZ endPoint;
				if (i == loop.Count - 1)
				{
					endPoint = loop[0];
				}
				else
				{
					endPoint = loop[i + 1];
				}
				EdgeInfo item = new EdgeInfo(startPoint, endPoint, 0.0);
				list.Add(item);
			}
			return new FillRegion(list, color);
		}

		private List<CurveInfo> m_Curves = new List<CurveInfo>();

		private List<TextNoteInfo> m_Texts = new List<TextNoteInfo>();

		private List<FillRegion> m_FillRegions = new List<FillRegion>();

		private Transform m_CurrentTransform;
	}
}
